package org.hzz.application.task;

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.gitee.pkmer.convention.page.PageResponse;
import io.gitee.pkmer.convention.page.query.FilterCondition;
import io.gitee.pkmer.convention.page.query.PageQuery;
import lombok.Setter;
import org.hzz.promotions.domain.entity.CouponEntity;
import org.hzz.promotions.domain.service.CouponDomainService;
import org.hzz.promotions.types.constants.CouponFields;
import org.hzz.promotions.types.enums.coupon.CouponStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

import static io.gitee.pkmer.convention.page.query.FilterCondition.Operation.EQ;
import static io.gitee.pkmer.convention.page.query.FilterCondition.Operation.LessOrEqual;

/**
 * @author <a href="mailto:1193094618@qq.com">pkmer</a>
 * <br>
 * <a href = "https://gitee.com/developeros/videos-online">Code Repository</a>
 * At 2024/9/1
 * 优惠券定时任务
 */
@Component
public class CouponIssueTaskHandler {

    @Setter(onMethod_ = @Autowired)
    private CouponDomainService couponDomainService;

    /**
     * 定时任务处理优惠券开始发放
     */
    @XxlJob("couponIssuingJobHandler")
    public void handleCouponIssuing() {
        // xxljob 分片处理,防止重复插入
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();

        // 分片以0开始
        int pageNo = shardIndex + 1;

        List<FilterCondition> filters = FilterCondition.createCriteria()
                .and(CouponFields.STATUS, EQ, CouponStatus.UN_ISSUE)
                .and(CouponFields.ISSUE_BEGIN_TIME, LessOrEqual, LocalDateTime.now())
                .build();

        PageQuery pageQuery = new PageQuery();
        pageQuery.setFilters(filters);

        while (true) {
            pageQuery.setPageNo(pageNo);
            if (!handleCouponStatus(CouponStatus.ISSUING, pageQuery)) {
                return;
            }
            // 继续下一页
            pageNo += shardTotal;
        }
    }


    /**
     * 处理优惠券发放已结束
     */
    @XxlJob("couponIssuedJobHandler")
    public void handleCouponIssued() {
        // xxljob 分片处理,防止重复插入
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();

        // 分片以0开始
        int pageNo = shardIndex + 1;

        List<FilterCondition> filters = FilterCondition.createCriteria()
                .and(CouponFields.STATUS, EQ, CouponStatus.ISSUING)
                .and(CouponFields.ISSUE_END_TIME, LessOrEqual, LocalDateTime.now())
                .build();

        PageQuery pageQuery = new PageQuery();
        pageQuery.setFilters(filters);
        while (true) {
            pageQuery.setPageNo(pageNo);
            if (!handleCouponStatus(CouponStatus.ISSUED, pageQuery)) {
                return;
            }
            // 继续下一页
            pageNo += shardTotal;
        }
    }


    /**
     * 优惠券状态处理
     *
     * @param status
     * @param pageQuery
     * @return 是否继续处理 true 继续; false 退出
     */
    private boolean handleCouponStatus(CouponStatus status, PageQuery pageQuery) {
        PageResponse<CouponEntity> pageResult = couponDomainService.pageQueryCoupon(pageQuery);
        if (pageResult.getTotal() == 0) {
            return false;
        }

        List<CouponEntity> entities = pageResult.getList();
        entities.forEach(entity -> entity.setStatus(status));

        couponDomainService.batchUpdateCouponEntity(entities);
        return true;
    }
}
